﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using StructureMap;
using System.Security.Cryptography;

namespace CarbonExchange.Tests
{
    [TestClass]
    public class BaseTest
    {
        [AssemblyInitialize()]
        public static void Init(TestContext context)
        {
            StructureMapConfiguration.ForRequestedType<AmeeQuery.IAmeeCommand>().TheDefaultIsConcreteType<AmeeQuery.AmeeCommand>().CacheBy(StructureMap.Attributes.InstanceScope.Hybrid);

            StructureMapConfiguration.ForRequestedType<CarbonExchange.AmeeQuery.IAmeeSettingsReader>().TheDefaultIsConcreteType<CarbonExchange.AmeeQuery.AmeeSettingsReader>();

            StructureMapConfiguration.ForRequestedType<CarbonExchange.Dal.Context>().TheDefaultIs(() => new CarbonExchange.Dal.Context(@"Data Source=.\SqlExpress;Initial Catalog=TestsCarbonExchange;Integrated Security=True;Pooling=False;Application Name=Tests"));

            StructureMapConfiguration.ForRequestedType<CarbonExchange.Logger.ILogger>().TheDefaultIsConcreteType<CarbonExchange.Logger.NLogLogger>();
        }

        protected Dal.Context _Context;
        protected Dal.AcmsSite _TestSite;
        protected Dal.AcmsSite _AlternateSite;
        protected List<Dal.Country> _TestCountries;
        protected List<string> _TestPasswords;
        protected List<int> _TestSalts;
        protected List<Dal.AcmsUser> _TestUsers;
        //protected List<Dal.User> _TestSuperUsers;
        protected List<Dal.EmailRestriction> _TestEmailRestrictions;
        //protected List<Dal.EmailActivationCode> _TestEmailActivationCodes;
        protected List<Dal.UserLoginKey> _TestUserLoginKeys;
        protected List<Dal.Audit> _TestAudits;
        protected List<Dal.Section> _TestSections;
        protected List<Dal.Question> _TestQuestions;
        protected List<Dal.SiteQuestion> _TestSiteQuestions;
        /*protected List<Dal.Template> _TestTemplates;
        protected List<Dal.TemplateFile> _TestTemplateFiles;
        protected List<Dal.TemplateHierarchy> _TestTemplateHierarchies;
        protected List<Dal.TemplateControlType> _TestTemplateControlTypes;
        protected List<Dal.TemplateControl> _TestTemplateControls;
        protected List<Dal.ContentNode> _TestContentNodes;
        protected List<Dal.ContentNodePosition> _TestContentNodePositions;*/
        protected List<Dal.Answer> _TestAnswers;
        protected List<Dal.AnswerItem> _TestAnswersItems;
        [TestInitialize]
        public void TestInit()
        {
            if (_Context == null)
            {
                _Context = StructureMap.ObjectFactory.GetInstance<Dal.Context>();
            }

            EnsureSiteData(_Context);
            EnsureCountryData(_Context);
            EnsureUsersData(_Context);
            EnsureEmailRestrictionData(_Context);
            EnsureAuditData(_Context);
            EnsureSectionData(_Context);
            EnsureQuestionData(_Context);
            _TestSiteQuestions = EnsureSiteQuestionData(_Context);
            _TestAnswers = EnsureAnswerData(_Context);
            _TestAnswersItems = EnsureAnswerItemData(_Context);
           
            //SaveChanges
            _Context.SubmitChanges();
        }

        private List<Dal.AnswerItem> EnsureAnswerItemData(Dal.Context context)
        {
            int noToGen = 65;
            var tmp = context.AnswerItems.OrderBy(x => x.Id).Take(noToGen).ToList();
            context.Answers.DeleteAllOnSubmit(context.Answers.OrderBy(x => x.Id).Skip(noToGen));

            while (tmp.Count < noToGen)
            {
                tmp.Add(new Dal.AnswerItem());
                context.AnswerItems.InsertOnSubmit(tmp.Last());
            }

            int i = 0;
            foreach (var item in tmp)
            {
                item.Answer = _TestAnswers[i % _TestAnswers.Count];
                item.Footprint = i % 15 == 0 ? null : new Nullable<decimal>(i * 100.249m);
                item.Name = string.Format("Answer Item Name {0}", i);
                item.Path = string.Format("Answer Item Path {0}", i);
                i++;
            }
            return tmp;
        }

        private List<Dal.Answer> EnsureAnswerData(Dal.Context context)
        {
            int answersToGen = 25;
            var tmp = context.Answers.OrderBy(x => x.Id).Take(answersToGen).ToList();
            context.Answers.DeleteAllOnSubmit(context.Answers.OrderBy(x => x.Id).Skip(answersToGen));

            while (tmp.Count < answersToGen)
            {
                tmp.Add(new Dal.Answer());
                context.Answers.InsertOnSubmit(tmp.Last());
            }

            int i = 0;
            foreach (var answer in tmp)
            {
                answer.Audit = _TestAudits[i % _TestAudits.Count];
                answer.Question = _TestQuestions[i % _TestQuestions.Count];
                answer.Settings = string.Concat("Settings ", i);
                i++;
            }
            return tmp;
        }

        /*private List<CarbonExchange.Dal.ContentNodePosition> EnsureContentNodePositionData(CarbonExchange.Dal.Context context)
        {
            int extraToGen = 3;
            var tmpList = context.ContentNodePositions.Take(_TestContentNodes.Count() + extraToGen).ToList();
            while(tmpList.Count() < _TestContentNodes.Count() + extraToGen)
            {
                tmpList.Add(new CarbonExchange.Dal.ContentNodePosition());
                tmpList.Last().Id = Guid.NewGuid();
                context.ContentNodePositions.InsertOnSubmit(tmpList.Last());
            }

            int i = 0;
            //create a position record for each post version
            foreach(var tmpNode in _TestContentNodes)
            {
                var tmp = tmpList[i];
                tmp.ContentNode = tmpNode;
                tmp.PublishDate = tmpNode.PublishFrom;

                var nodeIndex = _TestContentNodes.FindIndex(x => x.NodeGuid == tmpNode.NodeGuid);

                if (nodeIndex == 0)
                {
                    tmp.ParentNodeGuid = null;
                    tmp.ParentPath = null;
                    tmp.ParentSequence = null;
                    tmp.Sequence = 0;
                }
                else if (nodeIndex == 1 || nodeIndex == 2)
                {
                    tmp.ParentNodeGuid = _TestContentNodes[0].NodeGuid;
                    tmp.ParentPath = "~/";
                    tmp.ParentSequence = "0";
                    tmp.Sequence = nodeIndex - 1;
                }
                else
                {
                    tmp.ParentNodeGuid = _TestContentNodes[1].NodeGuid;
                    if (tmpNode.PublishFrom == null)
                    {
                        tmp.ParentPath = string.Format("~/{0}/", _TestContentNodes[1].Name);
                    }
                    else
                    {
                        var tmpName = _TestContentNodePositions.Where(x => x.PublishDate != null && x.PublishDate.Value == tmpNode.PublishFrom.Value && x.ParentNodeGuid == null).Single().ContentNode.Name;
                        tmp.ParentPath = string.Format("~/{0}/", tmpName);
                    }
                    tmp.ParentSequence = "00";
                    tmp.Sequence = nodeIndex - 3;
                }
                i++;
            }

            i = 0;
            for (i = 0; i < extraToGen; i++)
            {
                var tmp = tmpList[_TestContentNodes.Count() + i];
                tmp.ContentNode = _TestContentNodes.Where(x => x.NodeGuid == _TestContentNodes[1].NodeGuid && x.Id != _TestContentNodes[1].Id).First();
                tmp.ParentNodeGuid = tmp.ContentNode.ContentNodePositions[0].ParentNodeGuid;
                tmp.ParentPath = tmp.ContentNode.ContentNodePositions[0].ParentPath;
                tmp.ParentSequence = tmp.ContentNode.ContentNodePositions[0].ParentSequence;
                tmp.PublishDate = DateTime.UtcNow.AddDays(7 * (i + 1));
                tmp.Sequence = 0;
            }

            context.ContentNodePositions.DeleteAllOnSubmit(context.ContentNodePositions.Skip(_TestContentNodes.Count() + extraToGen));

            return tmpList;
        }*/

        /*private List<CarbonExchange.Dal.ContentNode> EnsureContentNodeData(CarbonExchange.Dal.Context context)
        {
            //number of versions of each post to create
            //length is the number of posts to create
            int[] nodesToGen = new int[] { 2, 4, 3, 1, 1, 1};

            List<CarbonExchange.Dal.ContentNode> tmpList = _Context.ContentNodes.OrderBy(x => x.Id).Take(nodesToGen.Sum()).ToList();
            while (tmpList.Count() < nodesToGen.Sum())
            {
                tmpList.Add(new CarbonExchange.Dal.ContentNode());
                context.ContentNodes.InsertOnSubmit(tmpList.Last());
            }

            int level = 0;
            int current = 0;
            while(level < nodesToGen.Max())
            {
                for(var n = 0; n < nodesToGen.Count(); n++)
                {
                    if (nodesToGen[n] > level)
                    {
                        var tmp = tmpList[current];
                        tmp.CreatedDateTime = DateTime.Parse("24/10/1975").ToUniversalTime();
                        tmp.Deleted = false;
                        tmp.DeveloperLocked = n % 2 == 0;
                        tmp.DisplayName = "Display Name {0}".Format(current);
                        if (n == 0)
                        {
                            tmp.Name = "~";
                        }
                        else
                        {
                            tmp.Name = "Name{0}".Format(n);
                        }
                        tmp.Notes = "Notes {0}".Format(current);
                        tmp.SiteId = _TestSite.Id;
                        tmp.Summary = "Summary {0}".Format(current);
                        tmp.Template = _TestTemplates[n % _TestTemplates.Count];
                        if (level > 1)
                        {
                            tmp.PublishFrom = DateTime.Parse("24/10/1975 12:00").AddMonths((level) * -1).ToUniversalTime();
                            tmp.PublishTo = DateTime.Parse("24/10/1975 12:00").AddMonths((level - 1) * -1).ToUniversalTime();
                            tmp.RequiresPublishing = false;
                            tmp.ReadyToPublish = false;
                        }
                        else if (level == 1)
                        {
                            tmp.PublishFrom = DateTime.Parse("24/10/1975 12:00").ToUniversalTime();
                            tmp.PublishTo = null;
                            tmp.RequiresPublishing = false;
                            tmp.ReadyToPublish = false;
                        }
                        else
                        {
                            tmp.ReadyToPublish = n % 2 == 0;
                            tmp.RequiresPublishing = n != 3;
                            tmp.PublishFrom = null;
                            tmp.PublishTo = null;
                        }

                        if(level == 0)
                        {
                            tmp.NodeGuid = Guid.NewGuid();
                        }
                        else
                        {
                            tmp.NodeGuid = tmpList[n].NodeGuid;
                        }
                        current++;
                    }
                }
                level++;
            }

            context.ContentNodes.DeleteAllOnSubmit(_Context.ContentNodes.OrderBy(x => x.Id).Skip(nodesToGen.Sum()));
            return tmpList;
        }*/

        /*private List<CarbonExchange.Dal.TemplateControl> EnsureTemplateControlData(Dal.Context context)
        {
            int noToGen = 4;
            List<CarbonExchange.Dal.TemplateControl> tmp = context.TemplateControls.OrderBy(x => x.Id).Take(noToGen).ToList();
            while (tmp.Count < noToGen)
            {
                tmp.Add(new CarbonExchange.Dal.TemplateControl());
                context.TemplateControls.InsertOnSubmit(tmp.Last());
            }
            int i = 0;
            foreach (var item in tmp)
            {
                item.Deleted = false;
                item.Name = "Template Control {0}".Format(i);
                item.Notes = "Notes {0}".Format(i);
                item.Sequence = i;
                item.Template = _TestTemplates[0];
                item.TemplateControlType = _TestTemplateControlTypes[i % _TestTemplateControlTypes.Count];
                i++;
            }

            context.TemplateControls.DeleteAllOnSubmit(context.TemplateControls.OrderBy(x => x.Id).Skip(noToGen));

            return tmp;
        }*/

        /*private List<CarbonExchange.Dal.TemplateControlType> EnsureTemplateControlTypeData(Dal.Context context)
        {
            int noUniversalToGen = 3;
            int noSpecificToGen = 2;
            List<CarbonExchange.Dal.TemplateControlType> tmp = context.TemplateControlTypes.OrderBy(x => x.Id).Take(noSpecificToGen + noUniversalToGen).ToList();
            while (tmp.Count() < noSpecificToGen + noUniversalToGen)
            {
                tmp.Add(new CarbonExchange.Dal.TemplateControlType());
                context.TemplateControlTypes.InsertOnSubmit(tmp.Last());
            }
            int i = 0;
            foreach (var item in tmp)
            {
                item.AdminDisplayControlType = "Acms.AdminDisplayControlType{0}".Format(i);
                item.AdminEditControlType = "Acms.AdminEditControlType{0}".Format(i);
                item.Deleted = false;
                item.FrontEndControlType = "Acms.FrontEndControlType{0}".Format(i);
                item.Name = "Template Control Type {0}".Format(i);
                item.Notes = "Notes {0}".Format(i);
                if (i < noUniversalToGen)
                {
                    item.SiteId = null;
                }
                else
                {
                    item.SiteId = _TestSite.Id;
                }
                i++;
            }
            context.TemplateControlTypes.DeleteAllOnSubmit(context.TemplateControlTypes.OrderBy(x => x.Id).Skip(noSpecificToGen + noUniversalToGen));
            return tmp;
        }*/

        /*private List<CarbonExchange.Dal.TemplateHierarchy> EnsureTemplateHierarchyData(Dal.Context context)
        {
            int noToGen = 4;

            var list = context.TemplateHierarchies.OrderBy(x => x.Id).Take(noToGen).ToList();
            while (list.Count < noToGen)
            {
                list.Add(new CarbonExchange.Dal.TemplateHierarchy());
                context.TemplateHierarchies.InsertOnSubmit(list.Last());
            }
            foreach (var tmp in list)
            {
                int i = list.IndexOf(tmp);
                tmp.Deleted = false;
                tmp.Parent = _TestTemplates[0];
                tmp.Child = _TestTemplates[i % _TestTemplates.Count];
                tmp.Sequence = i;
            }
            context.TemplateHierarchies.DeleteAllOnSubmit(context.TemplateHierarchies.Skip(noToGen));
            return list;
        }*/

        /*private List<CarbonExchange.Dal.TemplateFile> EnsureTemplateFileData(Dal.Context context)
        {
            int noToGen = 3 + _TestTemplates.Count;

            var list = context.TemplateFiles.OrderBy(x => x.Id).Take(noToGen).ToList();
            while (list.Count < noToGen)
            {
                list.Add(new CarbonExchange.Dal.TemplateFile());
                context.TemplateFiles.InsertOnSubmit(list.Last());
            }
            foreach (var tmp in list)
            {
                int i = list.IndexOf(tmp);
                if (i < _TestTemplates.Count)
                {
                    tmp.Template = _TestTemplates[i];
                    tmp.IsDefault = true;
                }
                else
                {
                    tmp.Template = _TestTemplates[0];
                    tmp.IsDefault = false;
                }
                tmp.Deleted = false;
                tmp.MasterPagePath = "~/MasterPage{0}.master".Format(i);
                tmp.Name = "Template File {0}".Format(i);
                tmp.Path = "~/Templates/File{0}.{1}".Format(i, i == 4 ? "asxc" : "aspx");
                tmp.Theme = "Theme{0}".Format(i);
            }
            context.TemplateFiles.DeleteAllOnSubmit(context.TemplateFiles.Skip(noToGen));
            return list;
        }*/

        /*private List<Dal.Template> EnsureTemplateData(Dal.Context context)
        {
            int noToGen = 3;
            var list = context.Templates.OrderBy(x => x.Id).Take(noToGen).ToList();
            while (list.Count < noToGen)
            {
                list.Add(new CarbonExchange.Dal.Template());
                context.Templates.InsertOnSubmit(list.Last());
            }
            foreach (var tmp in list)
            {
                tmp.Deleted = false;
                tmp.ExcludeFromSearch = false;
                tmp.Name = "Template {0}".Format(list.IndexOf(tmp));
                tmp.Notes = "Notes {0}".Format(list.IndexOf(tmp));
                tmp.SiteId = _TestSite.Id;
            }
            context.Templates.DeleteAllOnSubmit(context.Templates.Skip(noToGen));
            return list;
        }*/

        private List<Dal.SiteQuestion> EnsureSiteQuestionData(Dal.Context context)
        {
            int noToGen = 3;
            var list = context.SiteQuestions.OrderBy(x => x.Id).Take(noToGen).ToList();
            while (list.Count() < noToGen)
            {
                list.Add(new CarbonExchange.Dal.SiteQuestion());
                context.SiteQuestions.InsertOnSubmit(list.Last());
            }
            foreach (var tmp in list)
            {
                tmp.Created = DateTime.Parse("24/10/1975").ToUniversalTime();
                tmp.Deleted = false;
                tmp.Question = _TestQuestions[list.IndexOf(tmp) + 1];
                tmp.Sequence = list.IndexOf(tmp);
                tmp.SiteId = _TestSite.Id;
            }

            context.SiteQuestions.DeleteAllOnSubmit(context.SiteQuestions.OrderBy(x => x.Id).Skip(noToGen));
            return list;
        }

        private void EnsureQuestionData(Dal.Context context)
        {
            int questionsToGen = 4;
            _TestQuestions = context.Questions.OrderBy(x => x.Id).Take(questionsToGen).ToList();
            while (_TestQuestions.Count() < questionsToGen)
            {
                _TestQuestions.Add(new Dal.Question());
                context.Questions.InsertOnSubmit(_TestQuestions.Last());
            }

            for (int i = 0; i < questionsToGen; i++)
            {
                _TestQuestions[i].Created = DateTime.Parse("24/10/1975").ToUniversalTime();
                _TestQuestions[i].Deleted = false;
                _TestQuestions[i].Type = (int)Bll.QuestionTextConfiguration.QuestionTypes.Electricity;
                _TestQuestions[i].QuestionName = string.Format("Question {0}", i);
                _TestQuestions[i].Section = _TestSections[0];
            }

            context.Questions.DeleteAllOnSubmit(context.Questions.OrderBy(x => x.Id).Skip(questionsToGen));
        }

        private void EnsureSectionData(Dal.Context context)
        {
            int sectionsToGen = 3;

            _TestSections = context.Sections.OrderBy(x => x.Id).Take(sectionsToGen).ToList();

            while (_TestSections.Count() < sectionsToGen)
            {
                _TestSections.Add(new Dal.Section());
                context.Sections.InsertOnSubmit(_TestSections.Last());
            }

            string[] tmpNames = new string[]{"Energy", "Water", "Waste"};
            for (int i = 0; i < _TestSections.Count; i++)
            {
                _TestSections[i].Name = tmpNames[i];
                _TestSections[i].Deleted = false;
                _TestSections[i].Sequence = i;
                _TestSections[i].Created = DateTime.Parse("24/10/1975 12:00:00").ToUniversalTime();
            }

            var delSections = context.Sections.Skip(3);
            context.Sections.DeleteAllOnSubmit(delSections);
        }

        private void EnsureAuditData(Dal.Context context)
        {
            int auditsToGen = 8;
            _TestAudits = context.Audits.OrderBy(x => x.Id).Take(auditsToGen).ToList();
            for (int i = 0; i < auditsToGen; i++)
            {
                if (_TestAudits.Count() < i + 1)
                {
                    _TestAudits.Add(new CarbonExchange.Dal.Audit());
                    context.Audits.InsertOnSubmit(_TestAudits[i]);
                }
                //reset data
                _TestAudits[i].AuditKey = string.Format("GenAudit{0}", i);
                _TestAudits[i].Created = DateTime.Parse("24/10/1975").ToUniversalTime();
                _TestAudits[i].Deleted = false;
                _TestAudits[i].AcmsUser = _TestUsers[i % 2];
                _TestAudits[i].PeopleInHousehold = i+5;
                _TestAudits[i].CountryId = _TestCountries.First().Id;
                _TestAudits[i].State = string.Format("Country {0}", i);
            }
            foreach (var group in _TestAudits.GroupBy(x => x.AcmsUser))
            {
                var n = 0;
                foreach (var item in group)
                {
                    item.StartDate = DateTime.Parse("1/6/2000").AddYears(n).ToUniversalTime();
                    item.EndDate = item.StartDate.AddYears(1);
                    item.Completed = true;
                    n++;
                }
                group.Last().Completed = false;
            }
            context.Audits.DeleteAllOnSubmit(context.Audits.OrderBy(x => x.Id).Skip(auditsToGen));
        }

        /*private void EnsureUserLoginKeyData(Dal.Context context)
        {
            _TestUserLoginKeys = new List<CarbonExchange.Dal.UserLoginKey>();
            foreach (Dal.User user in _TestUsers)
            {
                if (context.UserLoginKeys.Where(x => x.UserId == user.Id).Count() == 0)
                {
                    _TestUserLoginKeys.Add(new Dal.UserLoginKey());
                    _TestUserLoginKeys[_TestUserLoginKeys.Count - 1].UserId = user.Id;
                    _TestUserLoginKeys[_TestUserLoginKeys.Count - 1].Id = Guid.NewGuid();
                    _TestUserLoginKeys[_TestUserLoginKeys.Count - 1].Created = DateTime.Parse("24/10/1975 12:00").ToUniversalTime();
                    context.UserLoginKeys.InsertOnSubmit(_TestUserLoginKeys[_TestUserLoginKeys.Count - 1]);
                }
                else
                {
                    _TestUserLoginKeys.Add(context.UserLoginKeys.Where(x => x.UserId == user.Id).OrderBy(x => x.Id).First());
                }
                context.UserLoginKeys.DeleteAllOnSubmit(context.UserLoginKeys.Where(x => x.UserId == user.Id).OrderBy(x => x.Id).Skip(1));
            }

            //delete all other keys
            var ids = (from u in _TestUsers select u.Id).ToArray();
            var del = context.UserLoginKeys.Where(x => !ids.Contains(x.UserId));
            context.UserLoginKeys.DeleteAllOnSubmit(del);
        }*/

        /*private void EnsureEmailActivationCodeData(Dal.Context context)
        {
            int itemsToCreate = 6;
            _TestEmailActivationCodes = context.EmailActivationCodes.OrderBy(x => x.Id).Take(itemsToCreate).ToList();
            for(int i = 0; i < itemsToCreate; i++)
            {
                if (_TestEmailActivationCodes.Count() < i + 1)
                {
                    _TestEmailActivationCodes.Add(new CarbonExchange.Dal.EmailActivationCode());
                    context.EmailActivationCodes.InsertOnSubmit(_TestEmailActivationCodes[i]);
                }
                _TestEmailActivationCodes[i].Activated = i % 3 == 0 ? true : false;
                _TestEmailActivationCodes[i].Code = string.Format("TestCode{0}", i);
                _TestEmailActivationCodes[i].Created = DateTime.Parse("24/10/2008 12:00:00").ToUniversalTime();
                _TestEmailActivationCodes[i].Deleted = false;
                _TestEmailActivationCodes[i].EmailAddress = string.Format("testEmailActivated{0}@email.com", i);
                _TestEmailActivationCodes[i].User = _TestUsers[i % _TestUsers.Count()];
            }
            var delete = context.EmailActivationCodes.OrderBy(x => x.Id).Skip(itemsToCreate);
            context.EmailActivationCodes.DeleteAllOnSubmit(delete);
        }*/
        /*
        private void EnsureSiteRootData(Dal.Context context)
        {
            CarbonExchange.Dal.SiteRoot testSiteRoot1 = context.SiteRoots.OrderBy(x => x.Id).FirstOrDefault();
            if (testSiteRoot1 == null)
            {
                testSiteRoot1 = new CarbonExchange.Dal.SiteRoot();
                context.SiteRoots.InsertOnSubmit(testSiteRoot1);
            }
            testSiteRoot1.SiteId = _TestSite.Id;
            testSiteRoot1.Default = true;
            testSiteRoot1.Url = "localhost/testing1";
            testSiteRoot1.Deleted = false;

            CarbonExchange.Dal.SiteRoot testSiteRoot2 = context.SiteRoots.OrderBy(x => x.Id).Skip(1).FirstOrDefault();
            if (testSiteRoot2 == null)
            {
                testSiteRoot2 = new CarbonExchange.Dal.SiteRoot();
                context.SiteRoots.InsertOnSubmit(testSiteRoot2);
            }
            testSiteRoot2.SiteId = _TestSite.Id;
            testSiteRoot2.Default = false;
            testSiteRoot2.Url = "localhost/testing2";
            testSiteRoot2.Deleted = false;

            CarbonExchange.Dal.SiteRoot alternateSiteRoot = context.SiteRoots.OrderBy(x => x.Id).Skip(2).FirstOrDefault();
            if (alternateSiteRoot == null)
            {
                alternateSiteRoot = new CarbonExchange.Dal.SiteRoot();
                context.SiteRoots.InsertOnSubmit(alternateSiteRoot);
            }
            alternateSiteRoot.SiteId = _AlternateSite.Id;
            alternateSiteRoot.Default = false;
            alternateSiteRoot.Url = "localhost/AlernateSiteRoot";
            alternateSiteRoot.Deleted = false;

            var deleteSiteRoots = context.SiteRoots.OrderBy(x => x.Id).Skip(3);

            context.SiteRoots.DeleteAllOnSubmit(deleteSiteRoots);
        }*/

        private void EnsureEmailRestrictionData(Dal.Context context)
        {
            _TestEmailRestrictions = context.EmailRestrictions.OrderBy(x => x.Id).Take(4).ToList();
            if (_TestEmailRestrictions.Count == 0)
            {
                _TestEmailRestrictions.Add(new CarbonExchange.Dal.EmailRestriction());
                context.EmailRestrictions.InsertOnSubmit(_TestEmailRestrictions[0]);
            }
            if (_TestEmailRestrictions.Count == 1)
            {
                _TestEmailRestrictions.Add(new CarbonExchange.Dal.EmailRestriction());
                context.EmailRestrictions.InsertOnSubmit(_TestEmailRestrictions[1]);
            }
            if (_TestEmailRestrictions.Count == 2)
            {
                _TestEmailRestrictions.Add(new CarbonExchange.Dal.EmailRestriction());
                context.EmailRestrictions.InsertOnSubmit(_TestEmailRestrictions[2]);
            }
            if (_TestEmailRestrictions.Count == 3)
            {
                _TestEmailRestrictions.Add(new CarbonExchange.Dal.EmailRestriction());
                context.EmailRestrictions.InsertOnSubmit(_TestEmailRestrictions[3]);
            }

            _TestEmailRestrictions[0].SiteId = _TestSite.Id;
            _TestEmailRestrictions[0].EmailFilter = "allow@mann.com";
            _TestEmailRestrictions[0].Deleted = false;
            _TestEmailRestrictions[0].Access = true;
            _TestEmailRestrictions[0].Created = DateTime.Parse("24/10/1975 12:00:00").ToUniversalTime();

            _TestEmailRestrictions[1].SiteId = _TestSite.Id;
            _TestEmailRestrictions[1].EmailFilter = @"^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z+])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$";
            _TestEmailRestrictions[1].Deleted = false;
            _TestEmailRestrictions[1].Created = DateTime.Parse("24/10/1975 12:00:00").ToUniversalTime();
            _TestEmailRestrictions[1].Access = true;

            _TestEmailRestrictions[2].SiteId = _TestSite.Id;
            _TestEmailRestrictions[2].EmailFilter = "deny@mann.com";
            _TestEmailRestrictions[2].Deleted = false;
            _TestEmailRestrictions[2].Access = false;
            _TestEmailRestrictions[2].Created = DateTime.Parse("24/10/1975 12:00:00").ToUniversalTime();

            _TestEmailRestrictions[3].SiteId = _TestSite.Id;
            _TestEmailRestrictions[3].EmailFilter = "*@email.com";
            _TestEmailRestrictions[3].Deleted = false;
            _TestEmailRestrictions[3].Access = true;
            _TestEmailRestrictions[3].Created = DateTime.Parse("24/10/1975 12:00:00").ToUniversalTime();

            var restrictionsToDelete = context.EmailRestrictions.Skip(4);
            context.EmailRestrictions.DeleteAllOnSubmit(restrictionsToDelete);
        }

        private void EnsureSiteData(Dal.Context context)
        {
            //create the testing site;
            _TestSite = context.AcmsSites.OrderBy(x => x.Id).FirstOrDefault();
            if (_TestSite == null)
            {
                _TestSite = new CarbonExchange.Dal.AcmsSite();
                context.AcmsSites.InsertOnSubmit(_TestSite);
            }
            _TestSite.Name = "Test Site";
            _TestSite.Deleted = false;
            //_TestSite.Created = DateTime.Parse("24/10/1975 12:00:00").ToUniversalTime();

            _AlternateSite = context.AcmsSites.OrderBy(x => x.Id).Skip(1).FirstOrDefault();
            if (_AlternateSite == null)
            {
                _AlternateSite = new CarbonExchange.Dal.AcmsSite();
                context.AcmsSites.InsertOnSubmit(_AlternateSite);
            }
            _AlternateSite.Name = "Alterante Site";
            _AlternateSite.Deleted = false;
            //_AlternateSite.Created = DateTime.Parse("24/10/1975 12:00:00").ToUniversalTime();

            var deleteSites = context.AcmsSites.OrderBy(x => x.Id).Skip(2);
            context.AcmsSites.DeleteAllOnSubmit(deleteSites);
        }

        private void EnsureCountryData(Dal.Context context)
        {
            //create the countries
            _TestCountries = context.Countries.OrderBy(x => x.Id).Take(2).ToList();

            if (_TestCountries.Count() == 0)
            {
                _TestCountries.Add(new CarbonExchange.Dal.Country());
                context.Countries.InsertOnSubmit(_TestCountries[0]);
            }
            if (_TestCountries.Count() == 1)
            {
                _TestCountries.Add(new CarbonExchange.Dal.Country());
                context.Countries.InsertOnSubmit(_TestCountries[1]);
            }

            //reset counrty properties
            _TestCountries[0].Locale = "EN-UK";
            _TestCountries[0].Created = DateTime.Parse("24/10/1975 12:00:00").ToUniversalTime();
            _TestCountries[0].SiteId = _TestSite.Id;
            _TestCountries[0].Deleted = false;

            _TestCountries[1].Locale = "EN-US";
            _TestCountries[1].Created = DateTime.Parse("24/10/1975 12:00:00").ToUniversalTime();
            _TestCountries[1].SiteId = _TestSite.Id;
            _TestCountries[1].Deleted = false;

            var deleteCountries = context.Countries.OrderBy(x => x.Id).Skip(2);
            context.Countries.DeleteAllOnSubmit(deleteCountries);
        }

        private void EnsureUsersData(Dal.Context context)
        {
            int usersToCreate = 5;
            int superUsersToCreate = 0;

            if (_TestPasswords == null)
            {
                _TestPasswords = new List<string>();
            }
            if (_TestSalts == null)
            {
                _TestSalts = new List<int>();
            }
            while (_TestSalts.Count < usersToCreate + superUsersToCreate)
            {
                _TestSalts.Add(CreateSalt());
            }
            while (_TestPasswords.Count < usersToCreate + superUsersToCreate)
            {
                _TestPasswords.Add(CreateEncodedPassword(string.Format("Password{0}", _TestPasswords.Count()), _TestSalts[_TestPasswords.Count()]));
            }

            _TestUsers = context.AcmsUsers.OrderBy(x => x.Id).Take(usersToCreate).ToList();
            for (int i = 0; i < usersToCreate; i++)
            {
                if (_TestUsers.Count() < i + 1)
                {
                    _TestUsers.Add(new CarbonExchange.Dal.AcmsUser());
                    context.AcmsUsers.InsertOnSubmit(_TestUsers[i]);
                }
                _TestUsers[i].SiteId = _TestSite.Id;
                _TestUsers[i].FirstName = "Test";
                _TestUsers[i].LastName = string.Format("User {0}", i);
                //_TestUsers[i].Comment = string.Format("Comment {0}", i);
                //_TestUsers[i].CountryId = _TestCountries[i % 2 == 0 ? 0 : 1].Id;
                _TestUsers[i].Created = DateTime.Parse(string.Format("24/10/197{0} 12:00:00", i)).ToUniversalTime();
                _TestUsers[i].Deleted = false;
                //_TestUsers[i].Department = string.Format("Department {0}", i);
                _TestUsers[i].EmailAddress = string.Format("testemail{0}@email.com", i);
                //_TestUsers[i].EmailAuthenticated = i % 2 == 0 ? true : false;
                _TestUsers[i].Salt = _TestSalts[i];
                _TestUsers[i].Password = _TestPasswords[i];
                //_TestUsers[i].Relative = i % 3 == 0 ? false : true;
               // _TestUsers[i].Anon = i % 4 == 0 ? true : false;
               // _TestUsers[i].State = string.Format("State{0}", i);
                //_TestUsers[i].ThumnailId = i + 100;
            }

            /*_TestSuperUsers = context.Users.OrderBy(x => x.Id).Skip(usersToCreate).Take(superUsersToCreate).ToList();
            for (int i = 0; i < superUsersToCreate; i++)
            {
                if (_TestSuperUsers.Count() < i + 1)
                {
                    _TestSuperUsers.Add(new CarbonExchange.Dal.User());
                    context.Users.InsertOnSubmit(_TestSuperUsers[i]);
                }
                _TestSuperUsers[i].FirstName = "Test";
                _TestSuperUsers[i].LastName = string.Format("Super User {0}", i);
                _TestSuperUsers[i].Comment = string.Format("Comment {0}", i);
                _TestSuperUsers[i].CountryId = _TestCountries[i % 2 == 0 ? 0 : 1].Id;
                _TestSuperUsers[i].Created = DateTime.Parse(string.Format("24/10/197{0} 12:00:00", i)).ToUniversalTime();
                _TestSuperUsers[i].Deleted = false;
                _TestSuperUsers[i].Department = string.Format("Department {0}", i);
                _TestSuperUsers[i].EmailAddress = string.Format("testsuperemail{0}@email.com", i);
                _TestSuperUsers[i].EmailAuthenticated = i % 2 == 0 ? true : false;
                _TestSuperUsers[i].Salt = _TestSalts[i + usersToCreate];
                _TestSuperUsers[i].Password = _TestPasswords[i + usersToCreate];
                _TestSuperUsers[i].Relative = i % 3 == 0 ? false : true;
                _TestSuperUsers[i].Anon = i % 4 == 0 ? true : false;
                _TestSuperUsers[i].State = string.Format("State{0}", i);
                _TestSuperUsers[i].ThumnailId = i + 100;
            }
            */
            context.Users.DeleteAllOnSubmit(context.Users.OrderBy(x => x.Id).Skip(usersToCreate + superUsersToCreate));
        }

        private string CreateEncodedPassword(string password, int salt)
        {
            // Create Byte array of password string
            ASCIIEncoding encoder = new ASCIIEncoding();
            Byte[] secretBytes = encoder.GetBytes(password);

            // Create a new salt
            Byte[] saltBytes = new Byte[4];
            saltBytes[0] = (byte)(salt >> 24);
            saltBytes[1] = (byte)(salt >> 16);
            saltBytes[2] = (byte)(salt >> 8);
            saltBytes[3] = (byte)(salt);

            // append the two arrays
            Byte[] toHash = new Byte[secretBytes.Length + saltBytes.Length];
            Array.Copy(secretBytes, 0, toHash, 0, secretBytes.Length);
            Array.Copy(saltBytes, 0, toHash, secretBytes.Length, saltBytes.Length);

            SHA1 sha1 = SHA1.Create();
            Byte[] computedHash = sha1.ComputeHash(toHash);
            return encoder.GetString(computedHash);
        }

        private int CreateSalt()
        {
            Byte[] _saltBytes = new Byte[4];
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            rng.GetBytes(_saltBytes);
            return ((((int)_saltBytes[0]) << 24) + (((int)_saltBytes[1]) << 16) + (((int)_saltBytes[2]) << 8) + ((int)_saltBytes[3]));
        }
    }
}
